/*
 * Wazuh Vulnerability Scanner - Unit Tests
 * Copyright (C) 2015, Wazuh Inc.
 * November 8, 2023.
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General Public
 * License (version 2) as published by the FSF - Free Software
 * Foundation.
 */

#include "cve5FB_test.hpp"
#include "cve5_generated.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/verifier.h"
#include "json.hpp"
#include <memory>
#include <string>
#include <vector>

namespace NSCve5FbTest
{
    const char* INCLUDE_DIRECTORIES[] {FLATBUFFER_SCHEMAS_DIR, nullptr};

    const char* SCHEMA_PATH {FLATBUFFER_SCHEMAS_DIR "cve5.fbs"};

    auto constexpr PUBLISHED_CVE {R"(
        {
            "containers":
            {
                "adp":
                [
                    {
                        "affected":
                        [
                            {
                                "defaultStatus": "unaffected",
                                "platforms":
                                [
                                    "bookworm"
                                ],
                                "product": "bash",
                                "vendor": "debian"
                            },
                            {
                                "defaultStatus": "affected",
                                "platforms":
                                [
                                    "bookworm"
                                ],
                                "product": "bash",
                                "vendor": "debian"
                            }
                        ],
                        "descriptions":
                        [
                            {
                                "lang": "en",
                                "value": "The /etc/profile.d/60alias.sh script in the Mandriva bash package for Bash 2.05b, 3.0, 3.2, 3.2.48, and 4.0 enables the --show-control-chars option in LS_OPTIONS, which allows local users to send escape sequences to terminal emulators, or hide the existence of a file, via a crafted filename."
                            }
                        ],
                        "providerMetadata":
                        {
                            "orgId": "79363d38-fa19-49d1-9214-5f28da3f3ac5"
                        },
                        "references":
                        [
                            {
                                "url": "https://security-tracker.debian.org/tracker/CVE-2010-0002"
                            }
                        ]
                    }
                ],
                "cna":
                {
                    "affected":
                    [
                        {
                            "cpes":
                            [
                                "cpe:2.3:a:gnu:bash:2.05:b:*:*:*:*:*:*"
                            ],
                            "defaultStatus": "unaffected",
                            "product": "bash b",
                            "vendor": "gnu",
                            "versions":
                            [
                                {
                                    "status": "affected",
                                    "version": "2.05"
                                }
                            ]
                        }
                    ],
                    "descriptions":
                    [
                        {
                            "lang": "en",
                            "value": "The /etc/profile.d/60alias.sh script in the Mandriva bash package for Bash 2.05b, 3.0, 3.2, 3.2.48, and 4.0 enables the --show-control-chars option in LS_OPTIONS, which allows local users to send escape sequences to terminal emulators, or hide the existence of a file, via a crafted filename."
                        }
                    ],
                    "metrics":
                    [
                        {
                            "cvssV2_0":
                            {
                                "accessComplexity": "LOW",
                                "accessVector": "LOCAL",
                                "authentication": "NONE",
                                "availabilityImpact": "PARTIAL",
                                "baseScore": 2.1,
                                "confidentialityImpact": "NONE",
                                "integrityImpact": "NONE",
                                "vectorString": "AV:L/AC:L/Au:N/C:N/I:N/A:P",
                                "version": "2.0"
                            },
                            "format": "CVSS"
                        }
                    ],
                    "problemTypes":
                    [
                        {
                            "descriptions":
                            [
                                {
                                    "description": "CWE-20",
                                    "lang": "en"
                                }
                            ]
                        }
                    ],
                    "providerMetadata":
                    {
                        "orgId": "00000000-0000-4000-A000-000000000000",
                        "shortName": "@redhat.com"
                    },
                    "references":
                    [
                        {
                            "name": "https://qa.mandriva.com/show_bug.cgi?id=56882",
                            "url": "https://qa.mandriva.com/show_bug.cgi?id=56882"
                        }
                    ]
                }
            },
            "cveMetadata":
            {
                "assignerOrgId": "00000000-0000-4000-A000-000000000000",
                "assignerShortName": "@redhat.com",
                "cveId": "CVE-2010-0002",
                "datePublished": "2010-01-14T18:30:00.000Z",
                "dateUpdated": "2011-08-08T04:00:00.000Z",
                "state": "PUBLISHED"
            },
            "dataType": "CVE_RECORD",
            "dataVersion": "5.0"
        }
    )"};

    auto constexpr REJECTED_CVE {R"(
        {
            "containers": {
                "cna": {
                    "providerMetadata": {
                        "dateUpdated": "2023-03-09T14:02:53Z",
                        "orgId": "00000000-0000-4000-A000-000000000003",
                        "shortName": "nvd"
                    },
                    "rejectedReasons": [
                        {
                            "lang": "en",
                            "value": "This candidate was in a CNA pool that was not assigned to any issues during 2022."
                        }
                    ]
                }
            },
            "cveMetadata": {
                "assignerOrgId": "00000000-0000-4000-A000-000000000003",
                "assignerShortName": "nvd",
                "cveId": "CVE-2022-26053",
                "datePublished": "2023-03-07T23:15:10Z",
                "dateUpdated": "2023-03-09T14:02:53Z",
                "state": "REJECTED"
            },
            "dataType": "CVE_RECORD",
            "dataVersion": "5.0"
        }
    )"};

    auto constexpr INVALID_CVE {R"( 
        {
            "unknowField": "unknownValue"
        }
    )"};
} // namespace NSCve5FbTest

using namespace NSCve5FbTest;

/**
 * @brief Test that a published CVE can be parsed.
 *
 */
TEST_F(Cve5FbTest, parsePublishedCve)
{
    // Load the schema
    std::string schema;
    EXPECT_TRUE(flatbuffers::LoadFile(SCHEMA_PATH, false, &schema));

    // Parse the schema and the published CVE
    flatbuffers::Parser parser;
    EXPECT_TRUE(parser.Parse(schema.c_str(), INCLUDE_DIRECTORIES));
    EXPECT_TRUE(parser.Parse(PUBLISHED_CVE));
}

/**
 * @brief Test that a rejected CVE can be parsed.
 *
 */
TEST_F(Cve5FbTest, parseRejectedCve)
{
    // Load the schema
    std::string schema;
    EXPECT_TRUE(flatbuffers::LoadFile(SCHEMA_PATH, false, &schema));

    // Parse the schema and the published CVE
    flatbuffers::Parser parser;
    EXPECT_TRUE(parser.Parse(schema.c_str(), INCLUDE_DIRECTORIES));
    EXPECT_TRUE(parser.Parse(REJECTED_CVE));
}

/**
 * @brief Test that an invalid CVE cannot be parsed.
 *
 */
TEST_F(Cve5FbTest, parseInvalidCve)
{
    // Load the schema
    std::string schema;
    EXPECT_TRUE(flatbuffers::LoadFile(SCHEMA_PATH, false, &schema));

    // Parse the schema and the published CVE
    flatbuffers::Parser parser;
    EXPECT_TRUE(parser.Parse(schema.c_str(), INCLUDE_DIRECTORIES));
    EXPECT_FALSE(parser.Parse(INVALID_CVE));
}
